package com.jinyun.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import com.jinyun.pojo.ElectronicFence;
import com.jinyun.pojo.User;
import com.jinyun.pojo.UserLocation;
import com.jinyun.utils.PolygonUtils;
import com.jinyun.vo.*;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
public class UserService1 {

    @Autowired
    private MongoTemplate mongoTemplate;



    /**
     * 查询人员列表
     *
     * @param userQueryVo
     * @return
     */
    public Object queryUserList(UserQueryVo userQueryVo) {
        PageResult pageResult = new PageResult();
        pageResult.setPageNum(userQueryVo.getPage());
        pageResult.setPagesize(userQueryVo.getPageSize());

        //查询MongoDB
        PageRequest pageRequest = PageRequest.of(userQueryVo.getPage() - 1,
                userQueryVo.getPageSize(), Sort.by(Sort.Order.desc("created")));
        Query query = new Query().with(pageRequest);
        List<User> userList = this.mongoTemplate.find(query, User.class);
        if (CollUtil.isEmpty(userList)) {
            return pageResult;
        }




        //TODO 查询百度地图接口服务，车辆是否超出电子围栏范围
        List<UserVo> userVoList = new ArrayList<>();
        userList.forEach(vehicle -> {
            UserVo userVo = UserVo.convert(vehicle);

            //查询是否超出电子围栏范围
//            Boolean result = this.electronicFenceService.checkUserElectronicFence(userVo.getRailId(), userVo.getUserId());
            boolean result = checkPointInFence(userVo.getRailId(), userVo.getCurrentPosition().getLat().toString(), userVo.getCurrentPosition().getLng().toString());

            userVo.setWarn(result ? "1" : "0");
            userVoList.add(userVo);
        });

        pageResult.setItems(userVoList);
        return pageResult;
    }


    public Object queryUserList1(UserQueryVo1 userQueryVo) {
        // 初始化分页结果对象
        PageResult pageResult = new PageResult();
        pageResult.setPageNum(userQueryVo.getPage());
        pageResult.setPagesize(userQueryVo.getPageSize());

        // 动态构建查询条件
        Criteria criteria = new Criteria();

        // 根据 UserQueryVo 中的字段构建查询条件

        if (userQueryVo.getName() != null && !userQueryVo.getName().isEmpty()) {
            criteria.and("userName").regex(Pattern.quote(userQueryVo.getName()), "i"); // 不区分大小写的正则匹配
        }
        // 可以继续添加其他的查询条件...

        // 构建查询请求
        Query query = new Query(criteria).with(PageRequest.of(userQueryVo.getPage() - 1, userQueryVo.getPageSize(), Sort.by(Sort.Order.desc("created"))));

        // 查询MongoDB
        List<User> userList = this.mongoTemplate.find(query, User.class);

        // 如果没有找到任何用户，则直接返回空的结果集
        if (CollUtil.isEmpty(userList)) {
            return pageResult;
        }

        // 处理查询到的用户列表，检查是否超出电子围栏范围
        List<UserVo> userVoList = userList.stream()
                .map(vehicle -> {
                    UserVo userVo = UserVo.convert(vehicle);
                    // 查询是否超出电子围栏范围
//                    Boolean result = this.electronicFenceService.checkUserElectronicFence(userVo.getRailId(), userVo.getUserId());
                    boolean result = checkPointInFence(userVo.getRailId(), userVo.getCurrentPosition().getLat().toString(), userVo.getCurrentPosition().getLng().toString());
                    userVo.setWarn(result ? "1" : "0");
                    return userVo;
                })
                .collect(Collectors.toList());

        pageResult.setItems(userVoList);
        return pageResult;
    }

    /**
     *    创建人员设备
     * @param user
     * @return
     */

    public Object createUser(User user) {
        Query query = Query.query(Criteria.where("userId").is(user.getUserId()));
        if (this.mongoTemplate.count(query, User.class) > 0) {
            return ErrorResult.builder()
                .errCode("500")
                .errMessage("该用户已经存在，请勿重复添加！").build();
        }

//        //将人员注册到百度鹰眼服务中，并且将其添加到电子围栏中
//        if (user.getDeviceId() != null && !user.getDeviceId().isEmpty()) {
//            Boolean result = this.electronicFenceService.addUserToElectronicFence(user);
//
//            if (!result) {
//                return ErrorResult.builder()
//                        .errCode("501")
//                        .errMessage("添加车辆到百度地图服务中失败！").build();
//            }
//        }

        //将数据保存到MongoDB中
        user.setCreated(System.currentTimeMillis());
        user.setUpdated(user.getCreated());
        this.mongoTemplate.save(user);

        return "success";
    }


    /**
     * 更新人员位置
     *
     * @param currentPosition 当前人员的位置
     * @return
     */
    public Boolean updateUserLocation( LocationNamePoint1 currentPosition) {
        String id = currentPosition.getId();
        User user = this.queryUserById(id);

        //将位置上报给百度鹰眼服务
        RunParamVo runParamVo = new RunParamVo();
        runParamVo.setSpeed(10d);//TODO 速度
        runParamVo.setLongitude(Convert.toDouble(currentPosition.getLng()));
        runParamVo.setLatitude(Convert.toDouble(currentPosition.getLat()));
//        Boolean result = this.baiduService.uploadLocation(id, runParamVo);
//        if (!result) {
//            return false;
//        }

        //自定义方法判断是否超出电子围栏范围
        boolean result1 = checkPointInFence(user.getRailId(), runParamVo.getLatitude().toString(), runParamVo.getLongitude().toString());
        if (!result1) {
            return false;
        }

        //位置数据存储到人员表中
        Query query = Query.query(Criteria.where("id").is(new ObjectId(id)));
        Update update = Update.update("currentPosition", currentPosition)
                .set("updated", System.currentTimeMillis());
        UpdateResult updateResult = this.mongoTemplate.updateFirst(query, update, User.class);

        //存入位置表UserLocation
        UserLocation userLocation = new UserLocation();
        userLocation.setLocation(new GeoJsonPoint(Convert.toDouble(currentPosition.getLng()), Convert.toDouble(currentPosition.getLat())));
        userLocation.setUserId(user.getId().toString());
        userLocation.setUpdated(System.currentTimeMillis());
        this.mongoTemplate.save(userLocation);

        return updateResult.getModifiedCount() == 1;
    }


    /**
     * 查询人员轨迹
     * @param id
     * @return
     */

    public User queryUserById(String id) {
        return this.mongoTemplate.findById(new ObjectId(id), User.class);
    }

    public Object deleteUserById(String id) {
//        User user = this.queryUserById(id);
//        boolean result = this.baiduService.deleteEntity(user.getId().toString());
//        if (result) {
            Query query = Query.query(Criteria.where("id").is(new ObjectId(id)));
            DeleteResult deleteResult = this.mongoTemplate.remove(query, User.class);
            return deleteResult.getDeletedCount() == 1;
//        }
//
//        return ErrorResult.builder()
//                .errCode("500")
//                .errMessage("删除用户失败！").build();


    }

    /**
     * 根据id查询用户轨迹
     * @param id
     * @param date
     * @return
     */

    public Object queryUserLocus(String id, String date) {
        // 解析传入的日期字符串为LocalDate对象，并创建一天的开始和结束时间点
        LocalDate localDate = LocalDate.parse(date);
        LocalDateTime startOfDay = localDate.atStartOfDay();
        LocalDateTime endOfDay = localDate.atTime(23, 59, 59);

        // 使用Criteria定义查询条件，确保userId匹配且updated在指定日期范围内
        Query query = new Query(
                Criteria.where("userId").is(id)
                        .andOperator(
                                Criteria.where("updated").gte(startOfDay),
                                Criteria.where("updated").lt(endOfDay.plusSeconds(1))
                        )
        );

        // 添加排序规则，按updated字段升序排序
        query.with(Sort.by(Sort.Direction.ASC, "updated"));
        // 执行查询并返回结果列表
        List<UserLocation> userLocations = mongoTemplate.find(query, UserLocation.class);

        // 只需要经纬度，将UserLocation转换为LocationPoint列表
        List<LocationPoint> points = userLocations.stream()
                .map(userLocation -> {
                    GeoJsonPoint location = userLocation.getLocation();
                    return new LocationPoint(location.getX()+"", location.getY()+"");
                })
                .collect(Collectors.toList());

        return points;

    }

    /**
     * 根据ID查询电子围栏并判断给定的经纬度是否在其范围内
     *
     * @param id   电子围栏的唯一标识符
     * @param lat  经纬度中的纬度
     * @param lng  经纬度中的经度
     * @return 如果点在电子围栏内，则返回true；否则返回false。
     */
    public boolean checkPointInFence(String id, String lat, String lng) {
        // 查询电子围栏
        Query query = new Query(Criteria.where("_id").is(id));

        ElectronicFence fence = mongoTemplate.findOne(query, ElectronicFence.class);
//        System.out.println("fence = " + fence);
        if (fence == null || fence.getMutiPoints() == null || fence.getMutiPoints().isEmpty()) {
            return false;
        }

        // 使用工具方法检查点是否在多边形内
        return PolygonUtils.isPointInPolygon(lat, lng, fence.getMutiPoints());
    }


}
